package com.abcd.interceptor

import android.text.TextUtils
import android.util.Log
import com.facebook.react.bridge.ModuleSpec
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.modules.network.NetworkInterceptorCreator
import com.facebook.react.modules.network.NetworkingModule
import com.facebook.react.shell.MainReactPackage
import okhttp3.logging.HttpLoggingInterceptor
import java.util.*
import kotlin.collections.ArrayList

/**
 * 自定义的MainReactPackage工具包
 * 1. 移除了官方添加的NetworkingModule模块
 * 2. 添加了带有拦截器的自定义的NetworkingModule模块
 * 3. 添加'com.squareup.okhttp3:logging-interceptor:3.10.0'
 * 4. 实现了网络访问时的日志打印
 * Created by mazaiting on 2018/6/13.
 */
class CustomMainReactPackage : MainReactPackage() {
  
  /**
   * 获取日志拦截器
   * @return Http日志拦截器
   */
  private fun getHttpLoggingInterceptor(): HttpLoggingInterceptor {
    // 新建
    val loggingInterceptor = HttpLoggingInterceptor(
            HttpLoggingInterceptor.Logger { message: String? ->
              if (!TextUtils.isEmpty(message)) {
                Log.d("OkHttp=====>", message)
              }
            }
    )
    loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY;
    return loggingInterceptor
  }
  
  override fun getNativeModules(context: ReactApplicationContext?): MutableList<ModuleSpec> {
    // 获取父类的模块
    val nativeModules = super.getNativeModules(context)
    return adjustModules(context, nativeModules)
  }
  
  /**
   * 矫正模块列表
   * @param context 上下文
   * @param nativeModules 模块列表
   */
  private fun adjustModules(context: ReactApplicationContext?, nativeModules: List<ModuleSpec>): MutableList<ModuleSpec> {
    // 创建拦截器，并添加Http拦截器
    val list = Arrays.asList(
            NetworkInterceptorCreator { getHttpLoggingInterceptor() }
    )
    // 拷贝模块
    val modules = ArrayList(nativeModules)
    // 遍历
    nativeModules.forEach { moduleSpec: ModuleSpec ->
      // 判断类型
      if (NetworkingModule::class.java == moduleSpec.type) {
        // 移除当前项
        modules.remove(moduleSpec)
        // 添加新项
        modules.add(ModuleSpec.nativeModuleSpec(
                NetworkingModule::class.java,
                { NetworkingModule(context, list) }
        ))
        return@forEach
      }
    }
    return modules
  }
}